#include "SetterBox.h"
#include "ui_SetterBox.h"
#include <QDebug>
#include <QMessageBox>
#include <QDir>
#include <QFileDialog>
#include <QSettings>
#include <QStandardPaths>
#include <QErrorMessage>
#include "globalprofile.h"


SetterBox::SetterBox(QWidget *parent) :
  QTabWidget(parent),
  ui(new Ui::SetterBox)
{
  ui->setupUi(this);

  ui->formatComboBox->clear();
  ui->formatComboBox->addItems(GlobalProfile::acceptableVideoFormats());

  ui->videoCodecComboBox->addItems(GlobalProfile::videoCodecMap().keys());

  ui->rateComboBox->clear();
  ui->rateComboBox->addItems(GlobalProfile::frameRates());

  ui->audioCodecComboBox->addItems(GlobalProfile::audioCodecMap().keys());

  connect(ui->ffmpegButton, &QToolButton::clicked, this, &SetterBox::chooseFFmpegPath);
  connect(ui->outDirButton, &QToolButton::clicked, this, &SetterBox::chooseOutDir);

  loadSettings();
}

SetterBox::~SetterBox()
{
  delete ui;
}


int SetterBox::criticalMsg(QString s)
{
  return QMessageBox::critical(this, tr("严重错误"), s, QMessageBox::Ok);
//  QErrorMessage box(this);
//  box.setWindowTitle(tr("选项有错误"));
//  box.showMessage(s);
//  box.exec();
//  return box.result();
}

void SetterBox::chooseOutDir()
{
  QString path;
  path = QFileDialog::getExistingDirectory(this, tr("指定目的位置"), QDir::homePath());
  if (! path.isEmpty())
    ui->outDirField->setText(QDir::toNativeSeparators(path));
}


void SetterBox::chooseFFmpegPath()
{
  QString path;
  path = QFileDialog::getOpenFileName(this, tr("查找FFMpeg"), QDir::homePath(),
                                      tr("FFMPEG程序文件(ffmpeg.exe ffmpeg)"));
  if (! path.isEmpty())
    ui->ffmpegField->setText(QDir::toNativeSeparators(path));
}

bool SetterBox::checkFields()
{
  if (ui->formatComboBox->currentText().trimmed().isEmpty()) {
    criticalMsg(tr("请输入合法的扩展名。"));
    return false;
  }

  if (ui->outDirField->text().trimmed().isEmpty()) {
    criticalMsg(tr("请输入目的位置路径。"));
    return false;
  }

  if (ui->ffmpegField->text().trimmed().isEmpty()) {
    criticalMsg(tr("FFMPEG程序位置未知！"));
    return false;
  }

  QDir outDir(ui->outDirField->text());
  if (! outDir.exists()) {
    criticalMsg(tr("目的位置不存在！"));
    return false;
  }
  /*
  QFileInfo ffmpegFile(ui->ffmpegField->text());
  if (! ffmpegFile.exists()) {
    criticalMsg(tr("FFMPEG命令不存在！"));
    return false;
  }
  */
  return true;
}


QStringList SetterBox::arguments(QString filePath)
{
  QStringList args;

  QFileInfo info(QDir::toNativeSeparators(filePath));

  QString inputPath = QDir::toNativeSeparators(info.absoluteFilePath());

  args << "-i" << addQuotes(inputPath);

  args << GlobalProfile::videoCodecMap()[ui->videoCodecComboBox->currentText()];

  if (! ui->sizeChecker->isChecked())
    args << "-s" << QString("%1x%2").arg(ui->sizeXSpin->value()).arg(ui->sizeYSpin->value());

  if (! ui->aspectChecker->isChecked())
    args << "-aspect" << QString("%1:%2").arg(ui->aspectXSpin->value()).arg(ui->aspectYSpin->value());

  if (! ui->rateChecker->isChecked())
    args << "-r" << ui->rateComboBox->currentText();

  if (! ui->bitrateChecker->isChecked())
    args << "-b:v" << QString("%1k").arg(ui->bitrateSpin->value());
  else
    args << "-qscale 0";

  args << GlobalProfile::audioCodecMap()[ui->audioCodecComboBox->currentText()];

  if (! ui->audioBitrateChecker->isChecked())
    args << "-b:a" << QString("%1k").arg(ui->audioBitrateSpin->value());

  if (ui->overwriteChecker->isChecked())
    args << "-y";
  else
    args << "-n";

  QString outPath = QDir::toNativeSeparators(ui->outDirField->text());
  if (! outPath.endsWith(QDir::separator()))
    outPath += QDir::separator();
  QString formatName = ui->formatComboBox->currentText();
  if (! formatName.startsWith("."))
    formatName = "." + formatName;
  QString baseName = info.completeBaseName();

  args << addQuotes(outPath + baseName + formatName);

  return args;
}

QString SetterBox::ffmpeg()
{
  return ui->ffmpegField->text();
}

QString SetterBox::fullLine(QString filePath)
{
  QStringList line("\"" + ffmpeg() + "\"");
  line << arguments(filePath);
  return line.join(" ");
}

QString SetterBox::addQuotes(QString s)
{
  return QString("\"%1\"").arg(s);
}










/*******************
 * 设置相关
 * ***************/


void SetterBox::loadSettings()
{
  QSettings settings;

  //formatComboBox
  QString format = settings.value("setterbox/format", "").toString();
  if (GlobalProfile::acceptableVideoFormats().contains(format)) {
    ui->formatComboBox->setCurrentText(format);
  } else {
    ui->formatComboBox->setCurrentIndex(0);
  }

  //outDirField
  QString out = settings.value("setterbox/out_dir", "").toString();
  ui->outDirField->setText(out);

  //ffmpegField
  QString ffPath = settings.value("setterbox/ffmpeg_path", "").toString();
  if (ffPath.isEmpty())
    ffPath = QStandardPaths::findExecutable("ffmpeg");
  if (ffPath.isEmpty()) {
    QStringList custom_paths;
    custom_paths << QDir::currentPath()
                 << QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
                 << QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
                 << QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)
                 << QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)
                 << QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
    auto _path = QStandardPaths::findExecutable("ffmpeg", custom_paths);
    ffPath = QDir::toNativeSeparators(_path);
  }
  if (ffPath.isEmpty()) {
#ifdef Q_OS_UNIX
    ffPath = "ffmpeg";
#else
    ffPath = "ffmpeg.exe";
#endif
  }

  ui->ffmpegField->setText(ffPath);

  //videoCodecComboBox
  QString vcodec = settings.value("setterbox/vcodec", "").toString();
  if (GlobalProfile::videoCodecMap().keys().contains(vcodec))
    ui->videoCodecComboBox->setCurrentText(vcodec);
  else
    ui->videoCodecComboBox->setCurrentIndex(0);

  //keepsize
  ui->sizeChecker->setChecked(settings.value("setterbox/keep_size", true).toBool());
  ui->sizeXSpin->setValue(settings.value("setterbox/size_x", 1920).toInt());
  ui->sizeYSpin->setValue(settings.value("setterbox/size_u", 1080).toInt());

  //aspect
  ui->aspectChecker->setChecked(
    settings.value("setterbox/keep_aspect", true).toBool()
  );
  ui->aspectXSpin->setValue(
    settings.value("setterbox/aspect_x", 16.0).toDouble()
  );
  ui->aspectYSpin->setValue(
    settings.value("setterbox/aspect_y", 9.0).toDouble()
  );

  //rate
  ui->rateChecker->setChecked(
    settings.value("setterbox/keep_rate", true).toBool()
  );
  QString f_rate = settings.value("setterbox/rate", "").toString();
  if (f_rate.isEmpty())
    ui->rateComboBox->setCurrentIndex(0);
  else
    ui->rateComboBox->setCurrentText(f_rate);

  //bitrate(video)
  ui->bitrateChecker->setChecked(settings.value("setterbox/keep_bitrate", true).toBool());
  ui->bitrateSpin->setValue(
    settings.value("setterbox/bitrate", 800.0).toDouble()
  );

  //audioCodec
  QString acodec = settings.value("setterbox/acodec", "").toString();
  if (GlobalProfile::audioCodecMap().keys().contains(acodec))
    ui->audioCodecComboBox->setCurrentText(acodec);
  else
    ui->audioCodecComboBox->setCurrentIndex(0);

  //audiobitrate
  ui->audioBitrateChecker->setChecked(
    settings.value("setterbox/keep_audio_bitrate", true).toBool()
  );
  ui->audioBitrateSpin->setValue(
    settings.value("setterbox/audio_bitrate", 128).toDouble()
  );

}//loadsettings


void SetterBox::saveSettings()
{
  QSettings settings;

  settings.beginGroup("setterbox");

  settings.setValue("format", ui->formatComboBox->currentText());
  settings.setValue("out_dir", ui->outDirField->text());
  settings.setValue("ffmpeg_path", ui->ffmpegField->text());
  settings.setValue("vcodec", ui->videoCodecComboBox->currentText());
  settings.setValue("keep_size", ui->sizeChecker->isChecked());
  settings.setValue("size_x", ui->sizeXSpin->value());
  settings.setValue("size_y", ui->sizeYSpin->value());
  settings.setValue("keep_aspect", ui->aspectChecker->isChecked());
  settings.setValue("aspect_x", ui->aspectXSpin->value());
  settings.setValue("aspect_y", ui->aspectYSpin->value());
  settings.setValue("keep_rate", ui->rateChecker->isChecked());
  settings.setValue("rate", ui->rateComboBox->currentText());
  settings.setValue("keep_bitrate", ui->bitrateChecker->isChecked());
  settings.setValue("bitrate", ui->bitrateSpin->value());
  settings.setValue("acodec", ui->audioCodecComboBox->currentText());
  settings.setValue("keep_audio_bitrate", ui->audioBitrateChecker->isChecked());
  settings.setValue("audio_bitrate", ui->audioBitrateSpin->value());

  settings.endGroup();

  qDebug() << "全部 SetterBox 选项存储完毕。";
}


void SetterBox::resetSettings()
{
  QSettings settings;
  settings.beginGroup("setterbox");
  settings.remove("");
  settings.endGroup();
  settings.endGroup();
  loadSettings();
  qDebug() << "SetterBox 全部选项已重置。";
}
